Const SCR_W = 16
Const SCR_H = 12

Const STATE_REP = 1
Const STATE_STRING = 2

Sub usage
	Print "$ packmap.exe in.map out.h w h tlock prefix [scrsizes]"
End Sub

Function even (i As Integer) As Integer 
	Return ((i And 1) = 0)
End Function

Dim As Integer x, y, xx, yy, nPant, mapW, mapH, i, j, dat, f, mapsize, decosize, scrsize
Dim As Integer mapWtiles, mapPants, tLock, locksI, state, tileStrI, decoT, decoCt, XYct
Dim As Integer counter
Dim As String o, prefix
Dim As uByte d, dp
'Redim As uByte m (0, 0)
'Redim As uByte decos (0, 0), decosI (0)
'Redim As uByte mOut (0, 0), mOutI (0)
Dim As uByte locks (63), tilestr (32)

' Sorry, but this is acting weird
Dim As uByte m (127, SCR_W * SCR_H - 1)
Dim As uByte decos (127, 127)
Dim As uByte decosXY (127, 127), XY (127)
Dim As uByte decosO (127, 127)
Dim As uByte decosI (127)
Dim As uByte decosOI (127)
Dim As uByte mOut (127, SCR_W * SCR_H - 1)
Dim As uByte mOutI (127)

If Command (6) = "" Then usage: End

Print "packmap ... ";

mapW = Val (Command (3))
mapH = Val (Command (4))
mapWtiles = mapW * SCR_W
mapPants = mapW * mapH
tLock = Val (Command (5))
prefix = Command (6)

' Read map to big array
'Redim m (mapPants - 1, SCR_W * SCR_H - 1)
' Max 64 decos as per screen
'Redim decos (mapPants - 1, 127)
'Redim decosI (mapPants - 1)
'Redim mOut (mapPants - 1, SCR_W * SCR_H - 1)
'Redim mOutI (mapPants - 1)

' Reset indexes (not needed, but good practice).
For i = 0 To mapPants - 1
	decosI (i) = 0
	decosOI (i) = 0
	mOutI (i) = 0
Next i
locksI = 0

f = Freefile
Open Command (1) For Binary as #f
i = 0: dp = 0
While Not Eof (f)
	' Read from file
	Get #f, , d
	' Screen coordinates
	xx = (i \ SCR_W) Mod  mapW
	yy = i \ (SCR_W * SCR_H * mapW)
	' Tile coordinates
	x = i Mod SCR_W
	y = (i \ mapWtiles) Mod SCR_H
	' screen number
	nPant = xx + yy * mapW
	' Is d a decoration' 
	If d > 16 Then
		' Write to decos
		decosXY (nPant, decosI (nPant)) = x * 16 + y
		decos (nPant, decosI (nPant)) = d
		decosI (nPant) = decosI (nPant) + 1
		' Reset to previous (so there's more repetitions)
		d = dp
	End If
	' Is d a lock' 
	If d = tLock Then
		locks (locksI) = nPant: locksI = locksI + 1
		locks (locksI) = x * 16 + y: locksI = locksI + 1
	End if
	' Write to big array
	m (nPant, x + y * SCR_W) = d
	' Previous one
	dp = d
	' Counter
	i = i + 1
Wend
Close #f

' Process decos
For nPant = 0 To mapPants - 1
	If decosI (nPant) Then
		For i = 0 To decosI (nPant) - 1
			decoT = decos (nPant, i)
			
			If decoT <> &Hff Then
				decoCT = 1
				XY (0) = decosXY (nPant, i)
				' Find more:
				For j = i + 1 To decosI (nPant) - 1
					If decos (nPant, i) = decos (nPant, j) Then
						' Found! DESTROY!
						XY (decoCT) = decosXY (nPant, j)
						decoCT = decoCT + 1
						decos (nPant, j) = &Hff
					End If
				Next j
				If decoCT = 1 Then
					' T | 128, XY
					decosO (nPant, decosOI (nPant)) = decoT Or 128: decosOI (nPant) = decosOI (nPant) + 1
					decosO (nPant, decosOI (nPant)) = XY (0): decosOI (nPant) = decosOI (nPant) + 1
				Else
					' T N XY XY XY XY...
					decosO (nPant, decosOI (nPant)) = decoT: decosOI (nPant) = decosOI (nPant) + 1
					decosO (nPant, decosOI (nPant)) = decoCT: decosOI (nPant) = decosOI (nPant) + 1
					For j = 0 To decoCT - 1
						decosO (nPant, decosOI (nPant)) = XY (j): decosOI (nPant) = decosOI (nPant) + 1
					Next j
				End If
			End If
		Next i
	End If
Next nPant

' Write output
f = Freefile
Open Command (2) For Output As #f
Print #f, "// Packed(TM) map"
Print #f, "// generated by packmap.exe"
Print #f, "// Copyleft 2015 The Mojon Twins"
Print #f, ""
Print #f, "// Map Size Is " & mapW & "x" & mapH
Print #f, "// Screen Size Is " & SCR_W & "x" & SCR_H
Print #f, ""
Print #f, "#define N_BOLTS_" & Ucase (prefix) & " " & (locksI \ 2)
Print #f, ""

mapsize = 0

' Write screens
Print #f, "// Packed map, raw"
Print #f, ""
Print #f, "const unsigned char map_" & prefix & "_tiles [] = { "
For nPant = 0 To mapPants - 1
	Print #f, "	";
	For i = 0 To SCR_W * SCR_H - 1 Step 2
		d = (m (nPant, i) Shl 4) Or (m (nPant, i + 1) And 15)
		Print #f, "0x" & Lcase (Hex (d, 2));
		mapsize = mapsize + 1
		If i < (SCR_W * SCR_H - 3) Or nPant < (mapPants - 1) Then Print #f, ", ";
	Next i
	Print #f, ""
Next nPant
Print #f, "};"

Print #f, ""
Print #f, "// Total map size in bytes is " & mapsize
Print #f, ""

' Write decos
decosize = 0
Print #f, "// Decorations"
Print #f, "// Format: [T N XY XY XY XY... (T < 128) | T XY (T >= 128)]"
Print #f, ""
For nPant = 0 To mapPants - 1
	If decosOI (nPant) Then
		Print #f, "const unsigned char map_" & prefix & "_decos_" & Lcase (Hex (nPant, 2)) & " [] = { ";
		For i = 0 To decosOI (nPant) - 1
			Print #f, "0x" & Lcase (Hex (decosO (nPant, i), 2)) & ", " ;
			decosize = decosize + 1
		Next i
		Print #f, "0x00 }; "
	End If
Next nPant
Print #f, ""
Print #f, "const unsigned char *map_" & prefix & "_decos [] = {"
For y = 0 To mapH - 1
	Print #f, "	";
	For x = 0 To mapW - 1
		nPant = x + y * mapW
		If decosOI (nPant) Then
			Print #f, "map_" & prefix & "_decos_" & Lcase (Hex (nPant, 2));
		Else 
			Print #f, "0";
		End If
		decosize = decosize + 2
		If x < mapW - 1 Or y < mapH - 1 Then Print #f, ", ";
	Next x
	Print #f, ""
Next y
Print #f, "};"
Print #f, ""
Print #f, "// Total decorations size in bytes is " & decosize
Print #f, ""

' Write locks
If locksI Then
	Print #f, "const unsigned char map_" & prefix & "_locks [] = {"
	Print #f, "	";
	For i = 0 To locksI - 1
		Print #f, "0x" & Lcase (Hex (locks (i), 2));
		If i < locksI - 1 Then Print #f, ", ";
	Next i
	Print #f, ""
	Print #f, "};"
	Print #f, ""
End If

' Exit cleanly
Close #f
Erase m, decos, decosI

Print " DONE!"
